package com.ruoyi.common.utils;

public class RC4Util {

    private static final int S_BOX_SIZE = 256;

    /**
     * RC4 加密方法
     *
     * @param data 明文数据
     * @param key  密钥
     * @return 加密后的字节数组
     */
    public static byte[] encrypt(byte[] data, byte[] key) {
        return rc4(data, key);
    }

    /**
     * RC4 解密方法
     *
     * @param encryptedData 加密后的数据
     * @param key           密钥
     * @return 解密后的字节数组
     */
    public static byte[] decrypt(byte[] encryptedData, byte[] key) {
        return rc4(encryptedData, key);
    }

    /**
     * RC4 加密/解密核心方法
     *
     * @param data 数据
     * @param key  密钥
     * @return 处理后的字节数组
     */
    private static byte[] rc4(byte[] data, byte[] key) {
        int[] sBox = new int[S_BOX_SIZE];
        int[] keyStream = new int[data.length];

        // 初始化 S 盒
        for (int i = 0; i < S_BOX_SIZE; i++) {
            sBox[i] = i;
        }

        // KSA 密钥调度算法
        int j = 0;
        for (int i = 0; i < S_BOX_SIZE; i++) {
            j = (j + sBox[i] + (key[i % key.length] & 0xFF)) % S_BOX_SIZE;
            swap(sBox, i, j);
        }

        // PRGA 伪随机生成算法
        j = 0;
        for (int i = 0; i < data.length; i++) {
            int a = sBox[i];
            j = (j + a) % S_BOX_SIZE;
            int b = sBox[j];
            swap(sBox, i, j);
            keyStream[i] = sBox[(a + b) % S_BOX_SIZE];
        }

        // 异或操作
        byte[] result = new byte[data.length];
        for (int i = 0; i < data.length; i++) {
            result[i] = (byte) (data[i] ^ keyStream[i]);
        }

        return result;
    }

    /**
     * 交换数组中的两个元素
     *
     * @param array 数组
     * @param i     第一个元素的索引
     * @param j     第二个元素的索引
     */
    private static void swap(int[] array, int i, int j) {
        int temp = array[i];
        array[i] = array[j];
        array[j] = temp;
    }

    public static void main(String[] args) {
        String key = "secretKey";
        String originalString = "Hello, World!";
        byte[] keyBytes = key.getBytes();
        byte[] originalBytes = originalString.getBytes();

        byte[] encryptedBytes = encrypt(originalBytes, keyBytes);
        System.out.println("Encrypted: " + bytesToHex(encryptedBytes));

        byte[] decryptedBytes = decrypt(encryptedBytes, keyBytes);
        System.out.println("Decrypted: " + new String(decryptedBytes));
    }

    /**
     * 将字节数组转换为十六进制字符串
     *
     * @param bytes 字节数组
     * @return 十六进制字符串
     */
    public static String bytesToHex(byte[] bytes) {
        StringBuilder sb = new StringBuilder();
        for (byte b : bytes) {
            sb.append(String.format("%02x", b));
        }
        return sb.toString();
    }
}
